package curves.sys;

import curves.Point;

public class MPoint implements Point {

    private double x;
    private double y;
    private double weight = 1.0;

    public MPoint(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public MPoint(double x, double y, double w) {
        this.x = x;
        this.y = y;
        this.weight = w;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double w) {
        this.weight = w;
    }

    @Override
    public String toString() {
        return "(x: " + new Double(getX()).intValue() + ", y: " + new Double(getY()).intValue() + ", w: " + weight + ")";
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof MPoint)) {
            return false;
        }
        MPoint m = (MPoint) o;

        if (m.getX() != this.getX() || m.getY() != this.getY()) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash += x;
        hash *= y;
        return hash;
    }

    public Point dot(double a) {
        return new MPoint(x * a, y * a);
    }

    public Point add(Point point) {
        return new MPoint(x + point.getX(), y + point.getY());
    }

    public Point part(Point point, double a) {
        double k = getWCof(a, point.getWeight(),getWeight());
        return new MPoint(x + (point.getX() - x) * k, y + (point.getY() - y) * k, (weight * (1.0 - a) + point.getWeight() * a));
    }


    protected double getWCof(double a, double w1, double w2) {
        return (1.0 - Math.pow((1.0 - a), w1 / w2));
    }

    public double distance(Point point) {
        double xx = (this.x - point.getX());
        double yy = (this.y - point.getY());
        return Math.sqrt(xx * xx + yy * yy);
    }

    public void setX(double x) {
        this.x = x;
    }

    public void setY(double y) {
        this.y = y;
    }

    public Point weight() {
        return new MPoint(x * weight, y * weight, weight);
    }

    public Point unweight() {
        return new MPoint(x / weight, y / weight, weight);
    }
}
